<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
	<meta http-equiv="content-type" content="text/html; charset=utf-8" />
	<title>Happy Table</title>
<script type="text/javascript" src='ajax.js'></script>
<script type="text/javascript" src='happy-table.js'></script>
</head>
<body>
<h1>happy-table使用说明</h1>
<p>作者：老鳖(tiandiou@163.com)</p>
<p>单位：北京讯鸟软件有限公司</p>
<p></p>
<p><a href='happy-table.js'>下载</a>内测版本</p>
<p><a target='_blank' href='http://tiandiou.blog.163.com/blog/static/2355668220091018544631/'>查看</a>博客版使用说明</p>
<div style="width:800px;">

<p>表格是页面上一种常用且有效的数据呈现方式，但在实际的使用过程中也有一些问题，比如表格数据条数或者列数太多，会产生滚动条，只有部分数据可见，或者看不见表头，根本不知道数据的含义。happy-table最初就是为了解决这一问题而开发的。happye-table功能特点：</p>
<p>*表头锁定，纵向滚动时，表头位置固定</p>
<p>*横向列锁定，当表横向滚动时，可以选中一列或者几列固定位置</p>
<p>*当页数据排序</p>
<p>*全屏显示</p>
<p>*良好的javas<wbr></wbr>cript编程接口</p>
<div style="height:220px;">
<div id="view" style="height:200px;width:600px;border:1px red solid;overflow:scroll;"></div>
</div>
<br />
<p>提示：</p>
<ul>
<li>双击表头的某一列，拖动横向滚动条，查看锁定或者释放</li>
<li>单击“注册时间”列，第一次按升序排列，第二次按降序排列</li>
<li>单击漂浮的工具条上的“全”，表格将全屏显示</li>
<li>单击漂浮的工具条上最后的“-”，隐藏工具条</li>
</ul>

<p>
本例中的js配置：<br />
<p>&nbsp;var settings = {};<br />
&nbsp;settings.URL = 'server.json';<br />
&nbsp;settings.view = 'view';<br />
&nbsp;var ajax = function(config){<br />
&nbsp;&nbsp;new Ajax(config.url, {onComplete:config.success});<br />
&nbsp;}<br />
&nbsp;settings.ajax = ajax;<br />
&nbsp;settings.isPaging = true;<br />
&nbsp;settings.showToolbar = true;</p>
<p>&nbsp;settings.op = {};<br />
&nbsp;settings.op.fields = {};<br />
&nbsp;settings.op.width = 50;<br />
&nbsp;settings.op.splitor = '|';<br />
&nbsp;settings.op.fields.remove = {<br />
&nbsp;&nbsp;text:'删除',<br />
&nbsp;&nbsp;listeners : {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;click:function(o, ev){if(confirm('Are you sure?')){o.remove();}ev.cancelBubble = true;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;};</p>
<p>&nbsp;var happyTable = new HappyTable(settings);<br />
&nbsp;happyTable.show();&nbsp;</p>

</p>

<p>下面说明如何使用happy-table。</p>
<p><font size="4">1、通信</font><br />
happy-table与服务器端通过ajax实现数据交互，服务器响应的数据组织方式为json。<br />
<br />
<font size="4">2、配置</font><br />
配置分为服务器端配置和浏览器端配置<br />
2.1、服务器端配置<br />
服务器端配置分为三部分：当前要显示的数据列表，数据总条数，数据列的呈现方式。三个参数将被组织在一个数组中，如<br />
$config = array(<br />
'da<wbr></wbr>ta' =&gt; $da<wbr></wbr>ta,<br />
'total' =&gt; $total,<br />
'header' =&gt; $header<br />
);<br />

下面将一一说明每个部分配置的详情</p>
<p><br />
<font size="4">2.1.1、数据列表</font><br />
数据列表对应了从数据库中进行select查询返回的<span style="color: rgb(255,0,0)">二维关连数组</span>，如<br />
$da<wbr></wbr>ta = $db-&gt;fetchAll(&quot;select * from table&quot;);<br />
<br />
<font size="4">2.1.2、数据条数</font><br />
在分页的情况下，可能一页不能显示全部数据，happy table需要知道总共有多少条数据，如果不分页，此参数可忽略。<br />
<br />
<font size="4">2.1.3、呈现配置</font><br />
按列对数据的呈现、功能进行配置。如：<br />
$header['book_id'] = array('title' =&gt; '书号', 'width'=&gt; 100, 'locked' =&gt; true);<br />
$header['title'] = array('title' =&gt; '书名', 'width'=&gt; 100, 'locked' =&gt; true);<br />
$header['class_id'] = array('title' =&gt; '分类', 'filter' =&gt; true, 'width'=&gt; 70, 'mapping' =&gt; array(&quot;1&quot;=&gt;'言情',&nbsp; &quot;2&quot;=&gt;'都市,&nbsp; &quot;3&quot;=&gt;'武侠',&nbsp; &quot;4&quot;=&gt;'玄幻',......));<br />
$header['author'] = array('title' =&gt; '作者', 'width'=&gt; 200, 'locked' =&gt; false);<br />
$header['register_time'] = array('title' =&gt; '注册时间', 'width'=&gt; 200, 'sort' =&gt; true);<br />
$header['last_update'] = array('title' =&gt; '最后更新','width'=&gt; 200);<br />
<br />
$header['book_id']中book_id与数据中的列名对应，表示要对数据列表中的列做配置，配置参数列表：<br />
title：呈现出来的名称<br />
width ：该列所占宽度<br />
locked：该列是否锁定<br />
mapping：一个关连数组，其中key是数据表中的值，value是要呈现出来的数据<br />
filter：该类是否有过滤器，如果是，将在标题栏上生成一个下拉列表，该下拉列表中的数据有配置项mapping配置项提供<br />
sort：是否可排序，如果是，点击标题栏时，数据列表会按照升序或者降序排列<br />
<br />
完成如上配置之后，将config数组转换为json格式输出即完成服务器端的流程。<br />
<br />
<font size="4">2.2、浏览器端配置</font><br />
在页面中引入happy-table的js文件，就可以构造happy-table的实例，构造实例需要一些配置参数，这些参数都写在一个对象当中，如：<br />
var happyTable = new HappyTable(settings);<br />
所有的配置选项都包含在settings这个对象中，下面将一一说明配置选项。<br />
2.2.1、最小基本配置<br />
settings.URL：服务端的url，如settings.URL = 'server.php';<br />
settings.view：用来呈现列表的容器的id或者dom对象，一般为div，如果不配置，默认为document.body<br />
settings.ajax：用来实现ajax交互的方法，该方法接收一个对象作为参数，如settings.ajax(ac)。其中ac.url说明要请求的地址，ac.success说明请求成功的回调函数。示例如下：<br />
&nbsp;&nbsp;&nbsp; var settings = {};<br />
&nbsp;&nbsp;&nbsp; settings.URL = 'server.php'<br />
&nbsp;&nbsp;&nbsp; settings.view = 'view';<br />
&nbsp;&nbsp;&nbsp; var ajax = function(config){<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; new Ajax(config.url, {on<wbr></wbr>Complete:config.success});//这部分根据你使用的ajax框架编写代码<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; settings.ajax = ajax;<br />
&nbsp;&nbsp;&nbsp; var happyTable = new HappyTable(settings);<br />
&nbsp;&nbsp;&nbsp; happyTable.show();//加载数据并呈现<br />
<br />
<font size="4">2.2.2、外观配置</font><br />
settings.css.happy-table预置了7个css的class名，可以通过这些样式来控制happy-table的外观。如：<br />
settings.css.rowSelected = 'row-selected';<br />
该配置表明如果行被选中，将按照class &ldquo;row-selected&rdquo;定义的样式来呈现。所有可配置的外观如下：<br />
settings.css.rowOdd : 奇数行样式&nbsp; <br />
settings.css.rowEven :偶数行的样式<br />
settings.css.rowHover:鼠标所在行的<br />
settings.css.rowSelected:选中行的样式</p>
<p>settings.css.header : 标题栏样式&nbsp; <br />
settings.css.table : 表体的样式&nbsp;&nbsp; <br />
settings.css.tools: 工具条的样式&nbsp; <br />
如果没有配置这些样式名，系统将会调用缺省样式。<br />
<br />
<font size="4">2.2.3、工具条与分页导航</font><br />
settings.showToolbar = false || true;<br />
如果该选项明确配置为false，将不显示工具条，否则显示工具条<br />
settings.isPaging = false || true;<br />
如果该选项明确配置为false，不显示分页条，否则显示分页条<br />
<br />
<font size="4">2.2.4、操作项配置</font><br />
按照习惯，一般会在表格的最后一列有一些操作项，如删除、修改等。<br />
&nbsp; settings.op = {};<br />
&nbsp; settings.op.width = 100;//操作列的宽度<br />
&nbsp; settings.op.splitor = '|';//操作项间的分割符号，如&ldquo;删除 | 修改&rdquo;<br />
&nbsp; settings.op.fields = {};//操作项目配置<br />
<br />
配置一个呈现为&rdquo;删除&ldquo;的操作项如下：<br />
settings.op.fields.remove = {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; text:'删除',<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; listeners : {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; click:function(o, ev){<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; alert('此操作将删除该行');<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ev.cancelBubble = true;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; },<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mouseover:function(o, ev){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ........<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; },.........&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; };<br />
其中&rdquo;remove&ldquo;这个字符串可自定义，一个操作项可以绑定多个js事件。如上的配置，当点击该操作是，会执行对应的方法，被触发的方法将接收到两个参数，第一个当前行的对象（请查看下面的文档），第二个为当前事件对象。<br />
&nbsp; <br />
<font size="4">2.3、事件监听</font></p>
<p><font size="4">2.3.1、可监听对象和事件</font><br />
happy-table的呈现结构被设计为view、tr、td三个层次，view指整个表，tr代表其中某一行，td代表某行的一个数据单元。客户程序可以对这些对象进行事件监听。需要注意的是，事件是向上冒泡的，如果不想要事件冒泡，可以在客户程序中取消冒泡。</p>
<p>view事件：scroll，mouseover，mouseout，click</p>
<p>tr事件：click，mouseover，mouseout</p>
<p>td事件：click，mouseover，mouseout</p>
<p><font size="4">2.3.2、事件宿主</font></p>
<p>被监听事件的宿主是指view、tr或者td的对象，从dom的角度，view为一div，tr是table的一行，td是tr的一个单元格，它们除了具有普通dom节点的属性和方法外，还有以下方法或者属性。</p>
<p>da<wbr></wbr>ta：宿主的数据，如果宿主是view，该属性是整个表格的数据，如果宿主是tr，该属性是一行数据，如果宿主是td，该属性是一个单元格中的数据。</p>
<p>draw：该方法可以重新绘制宿主的数据呈现，宿主的数据改变后，可以调用该方法将改变后的数据呈现。</p>
<p>remove：该方法为tr类型的宿主特有，调用该方法将宿主从表格呈现中移除，但是不会移除数据</p>
<p><font size="4">2.3.3、添加监听器</font></p>
<p>通过happy-table的on方法可以实现添加监听器：</p>
<p>happyTable.on(listenIn, event, callback);</p>
<p>语义为&ldquo;监听listenIn的event，如果event发生，调用callback&rdquo;。</p>
<p>listenIn：被监听对象，如view、tr、td</p>
<p>event：被监听的事件</p>
<p>callback：事件发生后的回调函数，该函数接受两个参数，第一个为被触发事件的宿主，第二个为事件本身，window.event的对象。</p>
<p>例如，需要对td的click事件进行监听</p>
<p>happyTable.on('td', 'click', function(o, ev){<br />
&nbsp;&nbsp;o.da<wbr></wbr>ta = '点我请掏钱';//修改数据<br />
&nbsp;&nbsp;o.draw();//重新绘制被单击的单元格</p>
<p>&nbsp; ev.cancelBubble = true;//取消单击事件的冒泡<br />
&nbsp;});</p>
<p>点击某个单元格后，单元格的数据被修改为&ldquo;点我请掏钱&rdquo;，并取消单击事件的冒泡（如果不取消，单元格所属的tr也会触发该单击事件）。</p>
<p><font size="4">2.4、分页显示</font></p>
<p>在加载数据的url中，如果启用分页，会发送两个GET参数_pi和_pg，_pi指明要取第几页，_pg指明每页多少条，分页的相关方法，请参看2.6小节</p>
<p><font size="4">2.5、公共属性</font></p>
<p>happyTable.data：当前这一页的数据</p>
<p><font size="4">2.6、公共方法</font></p>
<p>happyTable.draw()：绘制表格</p>
<p>happyTable.show()：根据配置从服务器加载数据，并调用happyTable.draw()绘制表格。</p>
<p>happyTable.configUrl(object)：将参数添加到请求url中，object为格式为{参数名:参数值,......}</p>
<p>happyTable.removeRow(rowIndex)：删除行号为rowIndex的行</p>
<p>happyTable.insertRow(da<wbr></wbr>ta, rowIndex)：将行数据da<wbr></wbr>ta插入到表格的rowIndex行，默认新插入的输入为最后一行</p>
<p>happyTable.getRow(rowIndex)：返回第rowIndex行</p>
<p>happyTable.sort(field, order)：根据field指示的列的值按照order指定的方式（升序或者降序）将表格排序，order为asc时升序，desc降序</p>
<p>happyTable.full()：全屏显示，在全屏显示和缩略显示之间切换显示方式</p>
<p>happyTable.getTotal()：当前表格的总条数</p>
<p>happyTable.on(listenIn, event, callback)：注册监听器，请参看2.3小节</p>
<p>happyTable.pager.load(pageIndex,&nbsp; perPage)：每页perPage条，加载第pageIndex页</p>
<p>happyTable.pager.prev()：加载上一页</p>
<p>happyTable.pager.first()：加载第一页</p>
<p>happyTable.pager.next()：加载下一页</p>
<p>happyTable.pager.last()：加载最后一页</p>
<p>happyTable.pager.getCurrentIndex()：取得当前第几页</p>
<p>happyTable.tools.show(visible)：设置工具条是否可见</p>
<p>&nbsp;</p>

<p>bug-报告：<a href="mailto:tiandiou@163.com">tiandiou@163.com</a></p>
</div>
<script type="text/javascript">
	var settings = {};
	settings.URL = 'server.json';
	settings.view = 'view';
	var ajax = function(config){
		new Ajax(config.url, {onComplete:config.success});
	}
	settings.ajax = ajax;
	settings.isPaging = true;
	settings.showToolbar = true;

	settings.op = {};
	settings.op.fields = {};
	settings.op.width = 50;
	settings.op.splitor = '|';
	settings.op.fields.remove = {
		text:'删除',
		listeners : {
						click:function(o, ev){if(confirm('Are you sure?')){o.remove();}ev.cancelBubble = true;}
					}
	};

	var happyTable = new HappyTable(settings);
	happyTable.show();
</script>
</body>
</html>